package com.topcent.tioxyc.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.topcent.tioxyc.constants.KeyConstant;
import com.topcent.tioxyc.pojo.ImgProcessEntity;
import com.topcent.tioxyc.pojo.vo.PicBaiduJdyResultVO;
import com.topcent.tioxyc.pojo.vo.PicBaiduResultVO;
import com.topcent.tioxyc.util.ApiClient;
import com.topcent.tioxyc.util.ConnmeUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.Header;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import java.io.*;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.net.URLEncoder;
import java.util.stream.Collectors;

/**
 * @author: 陈百万
 * @date: 2025/4/24 11:49
 * @Description: 图片检索控制类
 */
@RestController
@Slf4j
public class PictureSearchController {
    private static final String SECRET = "KPIfb04KeXBOWkj3m9xDqKV9";
    private static final String DATA_UPDATE = "data_update";
    public static final String API_KEY = "aymzNppOlaRmz0Kv1tG0OXIA";
    public static final String SECRET_KEY = "Luo4pdaIhXb7uHDtVJYDLbTl1e1GqgUS";
    public static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().readTimeout(300, TimeUnit.SECONDS).build();

    @PostMapping("/handleImgProcess")
    public String handleImgProcess(@RequestParam("nonce") String nonce,
                                   @RequestParam("timestamp") String timestamp,
                                   @RequestHeader("x-jdy-signature") String signature,
                                   @org.springframework.web.bind.annotation.RequestBody String payload){

        if (!validateSignature(nonce, payload, timestamp, signature)) {
            return "fail";
        }
        // 在这里处理消息
        handleData(payload);

        return "success";
    }

    private void handleData(String payload) {
        // 在这里处理推送来的数据
        JSONObject payloadJSON = JSONUtil.parseObj(payload);
        String op = payloadJSON.getStr("op");
        String data = payloadJSON.getStr("data");

        if (DATA_UPDATE.equals(op)) {
            update(data);
        }
    }

    private void update(String data){
        Header[] headers = ConnmeUtils.createHeaders();
        ImgProcessEntity imgProcessEntity = JSONUtil.toBean(data, ImgProcessEntity.class);
        String fileUrl = imgProcessEntity.get_widget_1745376087791().getFirst().getUrl(); // 简道云文件URL
        String savePath = "D:/aaa";
        String fileName = "jiandaoyun_download.jpg";
        String urla = downloadFileToServer(fileUrl, savePath,fileName);
        // 请求url
        String url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/realtime_search/similar/search";
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        Response response = null;
        // image 可以通过 getFileContentAsBase64("C:\fakepath\微信截图_20231108114357.png") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
        try {
            RequestBody body = RequestBody.create(mediaType, "image="+getFileContentAsBase64(urla, true));
            Request request = new Request.Builder()
                    .url(url + "?access_token=" + getAccessToken())
                    .method("POST", body)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded")
                    .build();
            response = HTTP_CLIENT.newCall(request).execute();
            String json = response.body().string();
            // 取出 result 数组
            JSONArray resultArray = JSONUtil.parseObj(json).getJSONArray("result");
            // 转为对象列表
            List<PicBaiduResultVO> picBaiduResultList = JSONUtil.toList(resultArray, PicBaiduResultVO.class).stream()
                    .filter(item -> item.getScore() != null && item.getScore() > 0.9)
                    .peek(item -> {
                        int scoreNum = (int) Math.round(item.getScore() * 100);
                        item.setScoreNum(scoreNum);
                        item.setScorePercent(scoreNum + "%");
                    }).toList();
            PicBaiduJdyResultVO picBaiduJdyResult = new PicBaiduJdyResultVO();
            PicBaiduJdyResultVO.PicBaidu jdyResult = new PicBaiduJdyResultVO.PicBaidu();
            for (PicBaiduResultVO picBaiduResultVO : picBaiduResultList) {
                jdyResult.set_widget_1745389588936(picBaiduResultVO.getCont_sign());
                jdyResult.set_widget_1745389588934(picBaiduResultVO.getScorePercent());
                jdyResult.set_widget_1745389588935(picBaiduResultVO.getBrief());
                jdyResult.set_widget_1745396579973(picBaiduResultVO.getScoreNum());
                picBaiduJdyResult.get_widget_1745389164938().add(jdyResult);
            }
            // 新增到简道云-查找类似产品表
            Map<String, Object> parameter = new HashMap<>();
            parameter.put("app_id", "667e34f0f58dbce6ca246f47");
            parameter.put("entry_id", "68085358981be1e0c7c44fde");
            parameter.put("data", ConnmeUtils.convertEntityToMap(picBaiduJdyResult));
            picBaiduJdyResult.set_id(null);
            String jsonSale = JSONUtil.toJsonStr(parameter);
            log.info("查找类似产品：==== {}", jsonSale);
            ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/create", headers, jsonSale);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取文件base64编码
     *
     * @param path      文件路径
     * @param urlEncode 如果Content-Type是application/x-www-form-urlencoded时,传true
     * @return base64编码信息，不带文件头
     */
    static String getFileContentAsBase64(String path, boolean urlEncode) throws IOException {
        byte[] b = Files.readAllBytes(Paths.get(path));
        String base64 = Base64.getEncoder().encodeToString(b);
        if (urlEncode) {
            base64 = URLEncoder.encode(base64, "utf-8");
        }
        return base64;
    }

    /**
     * 从用户的AK，SK生成鉴权签名（Access Token）
     *
     * @return 鉴权签名（Access Token）
     * @throws IOException IO异常
     */
    static String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY
                + "&client_secret=" + SECRET_KEY);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        return new JSONObject(response.body().string()).getStr("access_token");
    }

    public static String downloadFileToServer(String fileUrl, String saveDir, String fileName) {
        try (Response response = new OkHttpClient().newCall(
                new Request.Builder().url(fileUrl).build()
        ).execute()) {

            if (!response.isSuccessful()) {
                throw new IOException("下载失败: " + response.code());
            }

            Path filePath = Paths.get(saveDir, fileName);
            Files.write(filePath, response.body().bytes());

            return filePath.toFile().getAbsolutePath();
        } catch (IOException e) {
            throw new RuntimeException("下载失败", e);
        }
    }

    private boolean validateSignature(String nonce, String payload, String timestamp, String signature) {
        String calculatedSignature = getSignature(nonce, payload, PictureSearchController.SECRET, timestamp);
        return calculatedSignature.equals(signature);
    }

    private String getSignature(String nonce, String payload, String secret, String timestamp) {
        return DigestUtils.sha1Hex(nonce + ":" + payload + ":" + secret + ":" + timestamp);
    }
}
